package com.example.dayu521.gateway.conf;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.context.named.NamedContextFactory;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClientConfiguration;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;

//@Configuration
//@LoadBalancerClient(value = "msg-receive",configuration = LoadBalancerConf.CustomLoadBalancerConfiguration.class)
//@LoadBalancerClient(value = "msg-sender",configuration = LoadBalancerConf.CustomLoadBalancerConfiguration.class)

/**
 * {@link NamedContextFactory} 会先创建一个context,然后把servierid放到它的环境中,通过自动配置类{@link LoadBalancerClientConfiguration}创建
 * RoundRobinLoadBalancer,ServiceInstanceListSupplier
 * 注意到,这些都是在新的context中创建的,每个服务都会经过以上过程创建它对应的负载均衡环境
 * <a href="https://docs.spring.io/spring-cloud-commons/docs/current/reference/html/#eager-loading-of-loadbalancer-contexts">Eager loading of LoadBalancer contexts</a>
 */

@Slf4j
//@LoadBalancerClients(defaultConfiguration = LoadBalancerConf.CustomLoadBalancerConfiguration.class)
public class LoadBalancerConf {

    //ServiceInstanceListSupplier.builder()包含了装饰器模式,这种装饰器模式是按顺序循环应用装饰的功能,
    //而一般的装饰器模式是不停地嵌套新功能.使用循环避免了很多的栈空间
    public static final class CustomLoadBalancerConfiguration {

        @Bean
        public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
                ConfigurableApplicationContext context) {
            return ServiceInstanceListSupplier.builder()
                    .withDiscoveryClient()
                    .withWeighted(instance->{
//                        System.out.println("ddx");
                        return 0;
                    })
                    .withCaching()
                    .build(context);
        }
//        @Bean
//        ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
//                                                                LoadBalancerClientFactory loadBalancerClientFactory) {
//            String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
//            return new RandomLoadBalancer(loadBalancerClientFactory
//                    .getLazyProvider(name, ServiceInstanceListSupplier.class),
//                    name);
//        }
    }
}